package com.weiweiqin.controller.home;

import com.github.wxpay.sdk.WXPayUtil;
import com.weiweiqin.constants.PropertyConfig;
import com.weiweiqin.model.Customer;
import com.weiweiqin.model.Paylog;
import com.weiweiqin.service.PaylogService;
import com.weiweiqin.utils.DateTimeUtils;
import com.weiweiqin.utils.HttpUtil;
import com.weiweiqin.utils.PayCommonUtil;
import com.weiweiqin.utils.XMLUtil;
import com.weiweiqin.vo.common.Result;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.util.*;

@Controller
@RequestMapping("front/userPay")
public class FUserPayController {

	@Autowired
	private PaylogService paylogService;

	private static String WXPAY_MCHID="";

	static {
		WXPAY_MCHID = PropertyConfig.getInstance().getProperty("MCH_ID");
	}

	// 充值标识
	private Boolean czflg;

	private static final Logger logger = LoggerFactory
			.getLogger(FUserPayController.class);

	/**
	 * 微信H5支付
	 *
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping("/wxPayH5")
	public void wxPayH5(HttpServletRequest request, HttpServletResponse response, HttpSession session,BigDecimal amount) throws Exception {

		Map<String, Object> result = new HashMap<String, Object>();
		result.put("success", false);
		try {
			Paylog paylog = new Paylog();
			if(null == amount){
				paylog.setPrice(new BigDecimal(1));
			}else {
				paylog.setPrice(amount);
			}
			Customer customer = (Customer) session.getAttribute("customer");
			paylog.setCustomerId(customer.getId());
			paylog.setCreateTime(new Date());
			paylog.setStatus(1);
			paylog.setType(2);
			String orderNo = DateTimeUtils.formatTime(DateTimeUtils.getCurrentTime(), DateTimeUtils.yyyyMMddHHmmssSSS);
			paylog.setOrderNo(orderNo + customer.getId());
			paylogService.save(paylog);
			// 付款金额，必填
//            String total_fee = request.getParameter("WIDtotal_fee");
			String total_fee = paylog.getPrice().toString();
			// ip地址获取
			String basePath = request.getServerName() + ":" + request.getServerPort();
			// 账号信息
			String appid ="wx0951ff4c79108051"; // appid
			String mch_id = "1310531501"; // 商业号
			String key = "ab112233445566778899001122334455"; // key

			String currTime = PayCommonUtil.getCurrTime();
			String strTime = currTime.substring(8, currTime.length());
			String strRandom = PayCommonUtil.buildRandom(4) + "";
			String nonce_str = strTime + strRandom;
			// 价格 注意：价格的单位是分
			String order_price = new BigDecimal(total_fee).multiply(new BigDecimal(100)).toString().split("\\.")[0];
			// 自己网站上的订单号
			String out_trade_no = paylog.getOrderNo();
			// 获取发起电脑 ip
			String spbill_create_ip = HttpUtil.getRealIp(request);

			// 回调接口
			String notify_url = "http://youyijiashop.com/front/userPay/notifyh5";
			// 页面跳转同步通知页面路径
			String trade_type = "MWEB";

			// 设置package订单参数
			SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
			packageParams.put("appid", appid);
			packageParams.put("mch_id", mch_id);
			// 生成签名的时候需要你自己设置随机字符串
			packageParams.put("nonce_str", nonce_str);
			packageParams.put("out_trade_no", out_trade_no);
			packageParams.put("total_fee", order_price);
			packageParams.put("spbill_create_ip", spbill_create_ip);
			packageParams.put("notify_url", notify_url);
			packageParams.put("trade_type", trade_type);
			packageParams.put("body", "优一家充值");
			packageParams.put("scene_info", "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"http://sj.renwuwu.com\",\"wap_name\": \"任务屋商户系统\"}}");
			String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
			packageParams.put("sign", sign);
			String requestXML = PayCommonUtil.getRequestXml(packageParams);
			String resXml = HttpUtil.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", requestXML);
			Map map = XMLUtil.doXMLParse(resXml);
			String urlCode = (String) map.get("code_url");
			//确认支付过后跳的地址,需要经过urlencode处理
			String urlString = URLEncoder.encode("http://sj.renwuwu.com/meUserOrder/showAddOrder?id="+paylog.getId(), "UTF-8");
			String mweb_url = map.get("mweb_url")+"&redirect_url="+urlString;
			czflg = true;
			response.sendRedirect(mweb_url);
			result.put("sHtmlText", urlCode);
			result.put("success", true);
		} catch (Exception e) {
			result.put("errormsg", e.getMessage());
		}
	}

	/**
	 * 微信内置浏览器支付
	 *
	 * @param request
	 * @param response
	 * @throws Exception
	 */
	@RequestMapping("/wxPayJSAPI")
	@ResponseBody
	private Object wxPayJSAPI(HttpServletRequest request, HttpServletResponse response,HttpSession session,BigDecimal amount) throws Exception {
		logger.info("enter method wxPayJSAPI----------------------------------------------------");

		Result result = new Result();
		try {
			Paylog paylog = new Paylog();
			if(null == amount){
				paylog.setPrice(new BigDecimal(1));
			}else {
				paylog.setPrice(amount);
			}
			Customer customer = (Customer) session.getAttribute("customer");
			paylog.setCustomerId(customer.getId());
			paylog.setCreateTime(new Date());
			paylog.setStatus(1);
			paylog.setType(2);
			String orderNo = DateTimeUtils.formatTime(DateTimeUtils.getCurrentTime(), DateTimeUtils.yyyyMMddHHmmssSSS);
			paylog.setOrderNo(orderNo + customer.getId());
			paylogService.save(paylog);
			// 付款金额，必填
//            String total_fee = request.getParameter("WIDtotal_fee");
			String total_fee = paylog.getPrice().toString();
			// ip地址获取
			String basePath = request.getServerName() + ":" + request.getServerPort();
			// 账号信息
			String appid ="wx5523b103b7f04486"; // appid
			String mch_id = "1544576031"; // 商业号
			String key = "AA112233445566778899001122334Qww"; // key

			String currTime = PayCommonUtil.getCurrTime();
			String strTime = currTime.substring(8, currTime.length());
			String strRandom = PayCommonUtil.buildRandom(4) + "";
			String nonce_str = strTime + strRandom;
			// 价格 注意：价格的单位是分
			String order_price = new BigDecimal(total_fee).multiply(new BigDecimal(100)).toString().split("\\.")[0];
			// 自己网站上的订单号
			String out_trade_no = paylog.getOrderNo();
			// 获取发起电脑 ip
			String spbill_create_ip = HttpUtil.getRealIp(request);

			// 回调接口
			String notify_url = "http://youyijiashop.com/front/userPay/notifyh5";
			// 页面跳转同步通知页面路径
			String trade_type = "JSAPI";

			// 设置package订单参数
			SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
			packageParams.put("appid", appid);
			packageParams.put("mch_id", mch_id);
			// 生成签名的时候需要你自己设置随机字符串
			packageParams.put("nonce_str", nonce_str);
			packageParams.put("out_trade_no", out_trade_no);
			packageParams.put("total_fee", order_price);
//            packageParams.put("spbill_create_ip", spbill_create_ip);
			packageParams.put("spbill_create_ip", "123.12.12.123");
			packageParams.put("notify_url", notify_url);
			packageParams.put("trade_type", trade_type);
			packageParams.put("openid", customer.getOpenid());
//            packageParams.put("openid", "oB2TFvlJeaT2TNDmVW-wriIlQAkQ");
			packageParams.put("body", "优一家");
			packageParams.put("scene_info", "{\"h5_info\": {\"type\":\"Wap\",\"wap_url\": \"http://sj.renwuwu.com\",\"wap_name\": \"任务屋商户系统\"}}");
			String sign = PayCommonUtil.createSign("UTF-8", packageParams, key);
			packageParams.put("sign", sign);
			String requestXML = PayCommonUtil.getRequestXml(packageParams);
			String resXml = HttpUtil.postData("https://api.mch.weixin.qq.com/pay/unifiedorder", requestXML);
			logger.info("resXml="+resXml);
			Map map = XMLUtil.doXMLParse(resXml);
			if("SUCCESS".equals(map.get("result_code").toString()) && "SUCCESS".equals(map.get("result_code").toString())) {
				String prepay_id = map.get("prepay_id").toString();
				String appid1 = map.get("appid").toString();
				String nonce_str1 = map.get("nonce_str").toString();
				long timeStampSec = System.currentTimeMillis()/1000;
				String timeStamp = String.format("%010d", timeStampSec);
				SortedMap retrunMp = new TreeMap<Object, Object>();
				retrunMp.put("appId",appid1);
				retrunMp.put("timeStamp",timeStamp);
				retrunMp.put("nonceStr",nonce_str1);
				retrunMp.put("package","prepay_id="+prepay_id);
				retrunMp.put("signType","MD5");
				String paySign = PayCommonUtil.createSign("UTF-8", retrunMp, key);
				retrunMp.put("paySign",paySign);
				result.setObj(retrunMp);
				result.setResult(true);
				return result.toJson();
			}
			result.setResult(false);
			result.setErrorMsg("支付失败");
			return result.toJson();
		} catch (Exception e) {
			result.setResult(false);
			result.setErrorMsg("服务器错误");
			return result.toJson();
		}
	}

	@RequestMapping(value = "/notifyh5",method = {RequestMethod.GET, RequestMethod.POST})
	public void callBackh5(HttpServletRequest httpRequest,
						   HttpServletResponse httpResponse,HttpSession session) throws Exception {
		logger.info("----------------notifyh5");
		Map<String, String> returnWXMap = new HashMap<>();
		Map<String, String> notifyMap = getWxPayCallbackParams(httpRequest);
		String notifyXml = "";
		logger.info("notifyMap="+notifyMap.toString());
		// 签名正确
		// 进行处理。
		// 注意特殊情况：订单已经退款，但收到了支付结果成功的通知，不应把商户侧订单状态从退款改成支付成功
		if (notifyMap.get("result_code").toString().equalsIgnoreCase("SUCCESS") || notifyMap.get("return_code").toString().equalsIgnoreCase("SUCCESS")) {
			String mchId = notifyMap.get("mch_id");
			Integer totalFee = Integer.parseInt(notifyMap.get("total_fee"));
			Paylog paylog = paylogService.getByOrderNo(notifyMap.get("out_trade_no"));
			logger.info("paylog===="+paylog.toString());
			boolean result = false;
			if (null != paylog) {
				Double amount = (paylog.getPrice().doubleValue() * 100);
				if (WXPAY_MCHID.equals(mchId) && amount.intValue() == totalFee) {
					result = true;
				}
			}

			if (result) {
				logger.info("充值成功=" + notifyMap.get("transaction_id"));
				if (paylog.getStatus() == 1 && null==paylog.getTradeNo()) {
					paylog.setStatus(2);
					paylog.setTradeNo(notifyMap.get("transaction_id"));
					paylog.setPayTime(new Date());
					paylogService.reCharge(paylog);
					returnWXMap.put("return_code", "SUCCESS");
					returnWXMap.put("return_msg", "OK");
					notifyXml = WXPayUtil.mapToXml(returnWXMap);
					BufferedOutputStream out = new BufferedOutputStream(httpResponse.getOutputStream());
					out.write(notifyXml.getBytes());
					out.flush();
					out.close();
					return;
				}
			}
		}
		returnWXMap.put("return_code", "FAIL");
		returnWXMap.put("return_msg", "支付回调处理失败 ");
		notifyXml = WXPayUtil.mapToXml(returnWXMap);
		BufferedOutputStream out = new BufferedOutputStream(httpResponse.getOutputStream());
		out = new BufferedOutputStream(httpResponse.getOutputStream());
		out.write(notifyXml.getBytes());
		out.flush();
		out.close();
	}

	/**
	 * 获取微信支付回调请求参数
	 *
	 * @param request
	 * @return
	 * @throws Exception
	 */
	private Map<String, String> getWxPayCallbackParams(HttpServletRequest request) throws Exception {
		InputStream inStream = request.getInputStream();
		ByteArrayOutputStream outSteam = new ByteArrayOutputStream();
		byte[] buffer = new byte[1024];
		int len = 0;
		while ((len = inStream.read(buffer)) != -1) {
			outSteam.write(buffer, 0, len);
		}
		outSteam.close();
		inStream.close();
		String result = new String(outSteam.toByteArray(), "utf-8");
		//logger.info("getWxPayCallbackParams:" + result);
		return WXPayUtil.xmlToMap(result);
	}
}
